"""
中央空调主控制器
"""
from datetime import datetime
from typing import Dict, Optional
import threading
import time
from . import config
from .models import Request, RoomState
from .scheduler import Scheduler
from .service_object import ServiceObject


class CentralAC:
    """中央空调主控制器"""
    
    def __init__(self, total_rooms: int = config.TOTAL_ROOMS,
                 max_service_objects: int = config.MAX_SERVICE_OBJECTS):
        self.total_rooms = total_rooms
        self.scheduler = Scheduler(max_service_objects)
        
        # 初始化房间状态
        self.room_states: Dict[str, RoomState] = {}
        for i in range(1, total_rooms + 1):
            room_id = f"{i:03d}"
            self.room_states[room_id] = RoomState(
                room_id=room_id,
                current_temp=config.INITIAL_ROOM_TEMP,
                mode=config.MODE_COOLING
            )
        
        self.lock = threading.RLock()
        self.running = False
        self.update_thread: Optional[threading.Thread] = None
        
        # 记录上次请求时间（用于防止频繁请求）
        self.last_request_time: Dict[str, datetime] = {}
    
    def start(self):
        """启动中央空调系统"""
        with self.lock:
            if not self.running:
                self.running = True
                self.update_thread = threading.Thread(
                    target=self._update_loop, 
                    daemon=True
                )
                self.update_thread.start()
    
    def stop(self):
        """停止中央空调系统"""
        with self.lock:
            self.running = False
            if self.update_thread:
                self.update_thread.join(timeout=2)
    
    def _update_loop(self):
        """更新循环 - 定期更新温度和检查等待队列"""
        while self.running:
            try:
                self._update_all_temperatures()
                self.scheduler.check_waiting_queue(self.room_states)
                time.sleep(1)  # 每秒更新一次
            except Exception as e:
                print(f"更新循环出错: {e}")
    
    def _update_all_temperatures(self):
        """更新所有房间的温度"""
        with self.lock:
            current_time = datetime.now()
            
            for room_id, room_state in self.room_states.items():
                if not room_state.is_on:
                    continue
                
                # 计算时间间隔
                time_delta = (current_time - room_state.last_update_time).total_seconds()
                duration_minutes = time_delta / 60.0
                
                if room_state.is_serving:
                    # 正在服务中，计算温度变化
                    new_temp = ServiceObject.calculate_temp_change(
                        room_state.current_temp,
                        room_state.target_temp,
                        room_state.wind_speed,
                        room_state.mode,
                        duration_minutes
                    )
                    room_state.current_temp = round(new_temp, 2)
                    
                    # 连续计费：实时累计费用和耗电量
                    power_consumption = ServiceObject.calculate_power_consumption(
                        room_state.wind_speed, duration_minutes
                    )
                    cost = power_consumption * config.COST_PER_UNIT
                    room_state.total_power += power_consumption
                    room_state.total_cost += cost
                    
                    # 检查是否达到目标温度
                    if ServiceObject.is_target_reached(
                        room_state.current_temp, room_state.target_temp
                    ):
                        # 达到目标温度，停止送风
                        self.scheduler.release_service_by_room(room_id, self.room_states)
                else:
                    # 未服务状态，温度回归初始温度
                    new_temp = ServiceObject.calculate_temp_change_off(
                        room_state.current_temp,
                        config.INITIAL_ROOM_TEMP,
                        duration_minutes
                    )
                    room_state.current_temp = round(new_temp, 2)
                    
                    # 检查是否需要重新启动
                    if room_state.target_temp is not None:
                        if ServiceObject.should_restart(
                            room_state.current_temp,
                            room_state.target_temp,
                            room_state.mode
                        ):
                            # 自动发送重启请求
                            request = Request(
                                room_id=room_id,
                                target_temp=room_state.target_temp,
                                wind_speed=room_state.wind_speed,
                                mode=room_state.mode
                            )
                            self.scheduler.schedule_request(request, self.room_states)
                
                room_state.last_update_time = current_time
    
    def handle_request(self, room_id: str, target_temp: float, 
                      wind_speed: str, mode: str = None) -> dict:
        """处理温控请求
        
        Args:
            room_id: 房间号
            target_temp: 目标温度
            wind_speed: 风速
            mode: 模式（可选，默认使用房间当前模式）
            
        Returns:
            响应字典
        """
        with self.lock:
            # 检查房间是否存在
            if room_id not in self.room_states:
                return {
                    'success': False,
                    'message': f'房间{room_id}不存在'
                }
            
            room_state = self.room_states[room_id]
            
            # 检查请求间隔（防抖）
            current_time = datetime.now()
            if room_id in self.last_request_time:
                time_delta = (current_time - self.last_request_time[room_id]).total_seconds()
                if time_delta < config.REQUEST_INTERVAL_THRESHOLD:
                    # 间隔小于1秒，忽略之前的请求，只处理最后一次
                    pass
            
            self.last_request_time[room_id] = current_time
            
            # 使用指定模式或保持当前模式
            if mode is None:
                mode = room_state.mode
            
            # 验证温度范围
            if mode == config.MODE_COOLING:
                min_temp, max_temp = config.TEMP_RANGE_COOLING
                if not (min_temp <= target_temp <= max_temp):
                    return {
                        'success': False,
                        'message': f'制冷模式温度范围为{min_temp}-{max_temp}度'
                    }
            else:
                min_temp, max_temp = config.TEMP_RANGE_HEATING
                if not (min_temp <= target_temp <= max_temp):
                    return {
                        'success': False,
                        'message': f'制热模式温度范围为{min_temp}-{max_temp}度'
                    }
            
            # 验证风速
            if wind_speed not in config.WIND_PRIORITY:
                return {
                    'success': False,
                    'message': f'无效的风速: {wind_speed}'
                }
            
            # 开机
            if not room_state.is_on:
                room_state.is_on = True
                room_state.check_in_time = current_time
            
            # 更新房间状态的模式和目标温度（立即同步）
            room_state.mode = mode
            room_state.target_temp = target_temp
            room_state.wind_speed = wind_speed
            
            # 创建请求
            request = Request(
                room_id=room_id,
                target_temp=target_temp,
                wind_speed=wind_speed,
                mode=mode
            )
            
            # 调度请求
            scheduled = self.scheduler.schedule_request(request, self.room_states)
            
            if scheduled:
                return {
                    'success': True,
                    'message': '请求已接受，正在服务中',
                    'is_serving': True
                }
            else:
                return {
                    'success': True,
                    'message': '请求已接受，等待服务中',
                    'is_serving': False
                }
    
    def turn_off(self, room_id: str) -> dict:
        """关闭空调
        
        Args:
            room_id: 房间号
            
        Returns:
            响应字典
        """
        with self.lock:
            if room_id not in self.room_states:
                return {
                    'success': False,
                    'message': f'房间{room_id}不存在'
                }
            
            room_state = self.room_states[room_id]
            
            if not room_state.is_on:
                return {
                    'success': False,
                    'message': '空调未开机'
                }
            
            # 释放服务
            self.scheduler.release_service_by_room(room_id, self.room_states)
            
            # 关闭空调
            room_state.is_on = False
            room_state.is_serving = False
            room_state.is_waiting = False
            room_state.target_temp = None
            room_state.wind_speed = None
            
            return {
                'success': True,
                'message': '空调已关闭'
            }
    
    def get_room_state(self, room_id: str) -> Optional[dict]:
        """获取房间状态
        
        Args:
            room_id: 房间号
            
        Returns:
            房间状态字典
        """
        with self.lock:
            if room_id not in self.room_states:
                return None
            
            room_state = self.room_states[room_id]
            return {
                'room_id': room_id,
                'current_temp': room_state.current_temp,
                'target_temp': room_state.target_temp,
                'wind_speed': room_state.wind_speed,
                'mode': room_state.mode,
                'is_on': room_state.is_on,
                'is_serving': room_state.is_serving,
                'is_waiting': room_state.is_waiting,
                'total_cost': round(room_state.total_cost, 2),
                'total_power': round(room_state.total_power, 2)
            }
    
    def get_all_room_states(self) -> list:
        """获取所有房间状态"""
        with self.lock:
            return [
                self.get_room_state(room_id) 
                for room_id in sorted(self.room_states.keys())
            ]
    
    def get_monitoring_info(self) -> dict:
        """获取监控信息（供管理员使用）"""
        with self.lock:
            self.scheduler.update_service_durations()
            
            return {
                'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'service_queue': self.scheduler.get_service_queue_info(),
                'waiting_queue': self.scheduler.get_waiting_queue_info(),
                'room_states': self.get_all_room_states()
            }

